home *** CD-ROM | disk | FTP | other *** search
- #include "Q3ADUtilities.h"
-
- #include <assert.h>
- #include <stdlib.h>
- #include <math.h>
- #include <QD3DAcceleration.h>
-
- #include <QDOffscreen.h>
-
- /*
- ** CONSTANTS
- */
- #define kSize 1.0
- #define kSpace 1.0
-
- /*
- ** GLOBALS for the following functions
- */
- unsigned long gCurrentTicks = 0;
-
- typedef struct iTQ3ADOffscreen {
- GWorldPtr sourcePort;
- CGrafPtr destPort;
- Rect destRect;
- long dithered;
-
- } iTQ3ADOffscreen;
-
- static TQ3Status iOffscreen_ZeroOut(
- iTQ3ADOffscreen *ioOffscreen);
-
- TQ3RendererObject Q3ADUtility_NewRenderer(void)
- {
- TQ3RendererObject returnRenderer = NULL;
-
- returnRenderer = Q3Renderer_NewFromType(
- kQ3RendererTypeInteractive);
-
- if (!returnRenderer) goto bail;
-
- Q3InteractiveRenderer_SetDoubleBufferBypass (
- returnRenderer,
- kQ3False);
-
- Q3InteractiveRenderer_SetPreferences(
- returnRenderer,
- kQAVendor_BestChoice, 0);
-
- bail:
- return (returnRenderer);
- }
-
- TQ3DrawContextObject Q3ADUtility_NewMacDrawContext(
- CGrafPtr port,
- float paneSize)
- {
- TQ3DrawContextObject theDrawContext = NULL;
- TQ3ColorARGB white = { 1.0, 0.0, 0.0, 0.0 };
- TQ3Status status = kQ3Success;
-
- TQ3MacDrawContextData theMacDrawContextData;
-
- if(!port) goto bail;
-
- /*
- ** DrawContextData
- */
- #define mDCData theMacDrawContextData.drawContextData
-
- mDCData.clearImageMethod = kQ3ClearMethodWithColor;
- mDCData.clearImageColor = white;
- mDCData.paneState = kQ3True;
-
- {
- long width = (port->portRect.right - port->portRect.left) * 0.5,
- height = (port->portRect.bottom - port->portRect.top) * 0.5;
-
- mDCData.pane.min.x = (1.0 - paneSize) * width;
- mDCData.pane.min.y = (1.0 - paneSize) * height;
-
- mDCData.pane.max.x = (paneSize + 1) * width;
- mDCData.pane.max.y = (paneSize + 1) * height;
- }
-
- mDCData.maskState = kQ3False;
- mDCData.doubleBufferState = kQ3True;
-
-
- /*
- ** MAC DrawContextData
- */
- theMacDrawContextData.grafPort = (CGrafPort *) port;
- theMacDrawContextData.viewPort = NULL;
- theMacDrawContextData.window = (CGrafPort *) port;
- theMacDrawContextData.library = kQ3Mac2DLibraryQuickDraw;
-
- mBailIfNULL_(theDrawContext = Q3MacDrawContext_New(&theMacDrawContextData));
-
- bail:
- if (status == kQ3Failure) {
-
- if (theDrawContext) {
-
- Q3Object_Dispose(theDrawContext);
- theDrawContext = NULL;
- }
- }
-
- return (theDrawContext);
-
- #undef mDCData
-
- }
-
-
- TQ3ShaderObject Q3ADUtility_NewShader(void)
- {
- return Q3LambertIllumination_New();
- }
-
-
-
-
- /*===========================================================================*\
- *
- * Routine: Q3ADUtility_GetNumInRange()
- *
- * Comments: Returns a number within the range specified by width
- * and offset by offset. The number is parametrized within
- * "range" as below.
- *
- * EXAMPLE: 0 ------------------- 1 width: 0.5
- * | range | offset: 0.5
- *
- * EXAMPLE: 0 ------------------- 1 width: 0.5
- * | range | offset: 1.0
- *
- * EXAMPLE: 0 ------------------- 1 width: 0.25
- * |rnge| offset: 1.0
- *
- \*===========================================================================*/
-
- float Q3ADUtility_GetNumInRange(
- float number,
- float offset,
- float width)
- {
- if (width == 0.0) return offset;
-
- if (offset == 0.0) return (number * width);
-
- return (offset * (1 - width)) + (number * width);
- }
-
-
- /*===========================================================================*\
- *
- * Routine: Q3ADUtility_GetRectOfBestMonitor()
- *
- * Comments: Inputs the monitorsInfo data given by AD and returns the
- * Rect (in global coords) os the best monitor to draw into.
- *
- \*===========================================================================*/
-
- Rect Q3ADUtility_GetRectOfBestMonitor(
- MonitorsInfoPtr monitorsInfo)
- {
- int bestMonitor = 0;
- int idx = 0;
-
- assert(monitorsInfo);
-
- /*
- ** Here, we go through the list of monitors we are given,
- ** searching for the one with either the deepest bitdepth,
- ** or the first one that is 16 bit
- */
-
- for (idx = 0; idx < monitorsInfo->monitorCount; idx++)
- {
- if (monitorsInfo->monitorList[idx].curDepth == 16)
- {
- bestMonitor = idx;
- goto done;
- }
-
-
- if (monitorsInfo->monitorList[idx].curDepth >
- monitorsInfo->monitorList[bestMonitor].curDepth)
- {
- bestMonitor = idx;
- }
- }
-
- done:
- return monitorsInfo->monitorList[bestMonitor].bounds;
-
- }
-
-
- /*===========================================================================*\
- *
- * Routine: Q3ADUtility_GetBestMonitor()
- *
- * Comments: Inputs the monitorsInfo data given by AD and returns the
- * best monitor to draw into.
- *
- \*===========================================================================*/
-
- long Q3ADUtility_GetBestMonitor(
- MonitorsInfoPtr monitorsInfo)
- {
- long bestMonitor = 0;
- int idx = 0;
-
- assert(monitorsInfo);
-
- /*
- ** Here, we go through the list of monitors we are given,
- ** searching for the one with either the deepest bitdepth,
- ** or the first one that is 16 bit
- */
-
- for (idx = 0; idx < monitorsInfo->monitorCount; idx++)
- {
- if (monitorsInfo->monitorList[idx].curDepth == 16)
- {
- bestMonitor = idx;
- goto done;
- }
-
-
- if (monitorsInfo->monitorList[idx].curDepth >
- monitorsInfo->monitorList[bestMonitor].curDepth)
- {
- bestMonitor = idx;
- }
- }
-
- done:
- return bestMonitor;
-
- }
-
-
- /*===========================================================================*\
- *
- * Routine: TQ3Status_to_OSErr()
- *
- * Comments: Handles TQ3Statuses and returns an OSErr.
- *
- \*===========================================================================*/
-
- OSErr TQ3Status_to_OSErr(TQ3Status inStatus)
- {
-
- /*
- ** there's got to be a better error to return than userCanceledErr
- */
- if (inStatus == kQ3Success)
- return noErr;
- else return userCanceledErr;
- }
-
-
-
- #if 0
- #pragma mark -
- #endif
-
- /*===========================================================================*\
- *
- * Routine: Offscreen_New()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3ADOffscreen *Offscreen_New(
- CGrafPtr inDestPort,
- const Rect *inDestRect,
- long inDithered)
- {
- Rect gworldRect;
- iTQ3ADOffscreen *outOffscreen = NULL;
- TQ3Status status = kQ3Success;
-
- assert(inDestPort);
- assert(inDestRect);
-
- mBailIfNULL_(outOffscreen = malloc(sizeof(iTQ3ADOffscreen)));
-
- /*
- ** Save the internal preference as
- ** to whether it should be dithered or not
- */
- outOffscreen->dithered = inDithered;
-
- /*
- ** Saves off the destination port
- */
- outOffscreen->destPort = inDestPort;
-
- /*
- ** Grabs the rect that we are supposed to draw into.
- ** We also use it for the size for our own internal Gworld
- */
- outOffscreen->destRect = gworldRect = *inDestRect;
-
- /*
- ** So now, we normalize the rect for our GWorld (which
- ** we got from the above call)
- */
- OffsetRect(&gworldRect, -(gworldRect.top), -(gworldRect.left));
-
- /*
- ** Allocate it
- */
- if (NewGWorld(
- &outOffscreen->sourcePort,
- 16,
- &gworldRect,
- NULL,
- NULL,
- useTempMem) == noErr)
-
- {
- PixMapHandle hPixMap;
- CGrafPtr savedPort;
- GDHandle savedGDevice;
-
- GetGWorld(&savedPort, &savedGDevice);
- SetGWorld(outOffscreen->sourcePort, NULL);
-
- EraseRect(&outOffscreen->sourcePort->portRect);
-
- SetGWorld(savedPort, savedGDevice);
-
- hPixMap = GetGWorldPixMap (outOffscreen->sourcePort);
- HLock ((Handle) hPixMap);
- LockPixels (hPixMap);
-
- } else {
- status = kQ3Failure;
- goto bail;
- }
-
- bail:
-
- if (status == kQ3Failure) {
- if (outOffscreen) {
- free(outOffscreen);
- outOffscreen = NULL;
- }
- }
-
- return outOffscreen;
-
- }
-
-
- /*===========================================================================*\
- *
- * Routine: Offscreen_Dispose()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status Offscreen_Dispose(
- TQ3ADOffscreen *ioOffscreen)
- {
- if (ioOffscreen == NULL)
- return kQ3Success;
-
- {
- GWorldPtr tempGWorldPtr = NULL;
- PixMapHandle hPixMap;
-
- tempGWorldPtr = ioOffscreen->sourcePort;
-
- hPixMap = GetGWorldPixMap (tempGWorldPtr);
-
- HUnlock ((Handle) hPixMap);
- UnlockPixels (hPixMap);
-
- DisposeGWorld (tempGWorldPtr);
-
- }
-
- return kQ3Success;
-
- }
-
-
- /*===========================================================================*\
- *
- * Routine: iOffscreen_ZeroOut()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status iOffscreen_ZeroOut(
- iTQ3ADOffscreen *ioOffscreen)
- {
- assert(ioOffscreen);
-
- ioOffscreen->sourcePort = NULL;
- ioOffscreen->destPort = NULL;
- ioOffscreen->destRect.top =
- ioOffscreen->destRect.bottom =
- ioOffscreen->destRect.left =
- ioOffscreen->destRect.right = 0;
- ioOffscreen->dithered = 1;
-
- return kQ3Success;
- }
-
-
-
-
- /*===========================================================================*\
- *
- * Routine: Offscreen_Blit()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3Status Offscreen_Blit(
- TQ3ADOffscreen *inOffscreen)
- {
-
- assert(inOffscreen);
-
- {
- /*
- ** Sorry this is so ugly.
- */
-
- /*
- ** we have to save the last port
- */
- GWorldPtr savedPort;
- GDHandle tempGDHandle;
-
- /*
- ** These are used for *one* call, that being the one to CopyBits
- ** setting up the environment just so, will allow the fastest
- ** blitting
- */
-
- RGBColor savedForeground,
- savedBackground;
- RGBColor white = {0xFFFF, 0xFFFF, 0xFFFF};
- RGBColor black = {0, 0, 0};
- PixMapHandle offscreenBitmap = NULL;
- PixMapHandle destBitmap = NULL;
-
- /*
- ** save off the port
- */
- GetGWorld((GWorldPtr*)&savedPort, &tempGDHandle);
-
- /*
- ** now, we get ready to CopyBits. There is some setup to make it
- ** fast, so we do that first.
- */
- GetForeColor (&savedForeground);
- GetBackColor (&savedBackground);
-
- RGBForeColor (&black);
- RGBBackColor (&white);
-
- /*
- ** Grab the source and destination pixmaps
- */
- offscreenBitmap = GetGWorldPixMap (inOffscreen->sourcePort);
- destBitmap = GetGWorldPixMap (inOffscreen->destPort);
-
- /*
- ** Now for God knows why, we have to set the GWorld to the
- ** *destination* of our CopyBits or prepare to Restart.
- */
- SetPort((GrafPort *)inOffscreen->destPort);
-
-
- /*
- ** Again, for God knows why, we have to do a PenNormal here
- ** or CopyBits works weird.
- */
- PenNormal();
-
- /*
- ** do it.
- ** BTW, we use the fOffscreen->portRect twice because it's
- ** at 0,0 and that's what we want.
- */
- inOffscreen->dithered ?
-
- CopyBits ((const struct BitMap *)*offscreenBitmap,
- (const struct BitMap *)*destBitmap,
- &inOffscreen->sourcePort->portRect,
- &inOffscreen->destRect,
- srcCopy | ditherCopy, 0L)
-
- :
-
- CopyBits ((const struct BitMap *)*offscreenBitmap,
- (const struct BitMap *)*destBitmap,
- &inOffscreen->sourcePort->portRect,
- &inOffscreen->destRect,
- srcCopy, 0L)
-
- ;
-
- /*
- ** Restore all that stuff
- */
- RGBForeColor (&savedForeground);
- RGBBackColor (&savedBackground);
-
- /*
- ** We can't forget to restore our original port
- */
- SetGWorld((CGrafPtr)savedPort, tempGDHandle);
-
- }
-
- return kQ3Success;
-
- bail:
- return kQ3Failure;
- }
-
-
-
- /*===========================================================================*\
- *
- * Routine: Offscreen_NewPixmapDrawContext()
- *
- * Comments:
- *
- \*===========================================================================*/
-
- TQ3DrawContextObject Offscreen_NewPixmapDrawContext(
- TQ3ADOffscreen *inOffscreen)
- {
- TQ3DrawContextObject theDrawContext = NULL;
- TQ3ColorARGB white = { 1.0, 0.0, 0.0, 0.0 };
- TQ3Status status = kQ3Success;
-
- TQ3PixmapDrawContextData thePixmapDrawContextData;
-
- assert(inOffscreen);
-
- #define mDCData thePixmapDrawContextData.drawContextData
-
- mDCData.clearImageMethod = kQ3ClearMethodWithColor;
- mDCData.clearImageColor = white;
- mDCData.paneState = kQ3False;
- mDCData.maskState = kQ3False;
- mDCData.doubleBufferState = kQ3False;
-
- #define mPixmapData thePixmapDrawContextData.pixmap
-
- mPixmapData.image = GetPixBaseAddr (inOffscreen->sourcePort->portPixMap);
-
- mPixmapData.width = inOffscreen->sourcePort->portRect.right -
- inOffscreen->sourcePort->portRect.left;
-
- mPixmapData.height = inOffscreen->sourcePort->portRect.bottom -
- inOffscreen->sourcePort->portRect.top;
-
- mPixmapData.rowBytes = (**(inOffscreen->sourcePort->portPixMap)).rowBytes & 0x3FFF;
- mPixmapData.pixelSize = (**(inOffscreen->sourcePort->portPixMap)).pixelSize;
-
- switch((**(inOffscreen->sourcePort->portPixMap)).pixelSize)
- {
- case 16:
- mPixmapData.pixelType = kQ3PixelTypeRGB16;
- break;
-
- case 32:
- mPixmapData.pixelType = kQ3PixelTypeRGB32;
- break;
-
- default:
- goto bail;
- break;
- };
-
- mPixmapData.bitOrder = kQ3EndianBig;
- mPixmapData.byteOrder = kQ3EndianBig;
-
- mBailIfNULL_(theDrawContext = Q3PixmapDrawContext_New(&thePixmapDrawContextData));
-
-
- bail:
- if (status == kQ3Failure) {
- if (theDrawContext) {
- Q3Object_Dispose(theDrawContext);
- theDrawContext = NULL;
- }
- }
-
- return theDrawContext;
-
- #undef mPixmapData
- #undef mDCData
-
- }
-
-